# -*- coding:utf-8 -*-
# created on 2017/3/6
#

from mathsolver.functions.base import *
from sympy import Mul


def get_express_args(expr):
    childrens = []
    if hasattr(expr, "args"):
        for arg in expr.args:
            p = r'vector\(.*?\)'
            m = re.findall(p, str(arg))
            m = set(m)
            m = list(m)
            if len(m) == 1:
                childrens.append(arg)
            else:
                childrens.extend(get_express_args(arg))
        return childrens
    else:
        return childrens


def triangle_vector_simplify(expr_list, target):
    for item in expr_list:
        left = item[0]
        right = item[1]
        left_coeff = None
        left_vector_zuo = None
        left_vector_you = None
        right_coeff = None
        right_vector_zuo = None
        right_vector_you = None
        if isinstance(left, Mul):
            left_coeff = left.args[0]
            left_vector = left.args[1]
            left_vector_zuo = str(left_vector.args[0])[0]
            left_vector_you = str(left_vector.args[0])[1]
        else:
            if str(left.func) == "vector":
                left_coeff = 1
                left_vector_zuo = str(left.args[0])[0]
                left_vector_you = str(left.args[0])[1]
        if isinstance(right, Mul):
            right_coeff = right.args[0]
            right_vector = right.args[1]
            right_vector_zuo = str(right_vector.args[0])[0]
            right_vector_you = str(right_vector.args[0])[1]
        else:
            if str(right.func) == "vector":
                right_coeff = 1
                right_vector_zuo = str(right.args[0])[0]
                right_vector_you = str(right.args[0])[1]
        if left_coeff == right_coeff:
            if left_vector_you == right_vector_zuo:
                if left_vector_zuo == right_vector_you:
                    new_vector_value = target - left - right
                else:
                    new_vector = left_vector_zuo + right_vector_you
                    new_vector = "vector(%s)" % sympify(new_vector)
                    new_vector_value = target - left - right + left_coeff * sympify(new_vector)
                new_express_args = get_express_args(new_vector_value)
                new_express_zuhe = list(itertools.combinations(new_express_args, 2))
                if not new_express_zuhe:
                    return new_vector_value
                else:
                    new_vector_value = triangle_vector_simplify(new_express_zuhe, new_vector_value)
                    return new_vector_value
            elif left_vector_zuo == right_vector_you:
                if left_vector_you == right_vector_zuo:
                    new_vector_value = target - left - right
                else:
                    new_vector = right_vector_zuo + left_vector_you
                    new_vector = "vector(%s)" % sympify(new_vector)
                    new_vector_value = target - left - right + left_coeff * sympify(new_vector)
                new_express_args = get_express_args(new_vector_value)
                new_express_zuhe = list(itertools.combinations(new_express_args, 2))
                if not new_express_zuhe:
                    return new_vector_value
                else:
                    new_vector_value = triangle_vector_simplify(new_express_zuhe, new_vector_value)
                    return new_vector_value
        elif left_coeff + right_coeff == 0:
            if left_vector_zuo == right_vector_zuo:
                if (left_coeff > 0) and (right_coeff < 0):
                    new_vector = right_vector_you + left_vector_you
                    new_vector = "vector(%s)" % sympify(new_vector)
                    new_vector_value = target - left - right + sympify(new_vector)
                    new_express_args = get_express_args(new_vector_value)
                    new_express_zuhe = list(itertools.combinations(new_express_args, 2))
                    if not new_express_zuhe:
                        return new_vector_value
                    else:
                        new_vector_value = triangle_vector_simplify(new_express_zuhe, new_vector_value)
                        return new_vector_value
                elif (left_coeff < 0) and (right_coeff > 0):
                    new_vector = left_vector_you + right_vector_you
                    new_vector = "vector(%s)" % sympify(new_vector)
                    new_vector_value = target - left - right + sympify(new_vector)
                    new_express_args = get_express_args(new_vector_value)
                    new_express_zuhe = list(itertools.combinations(new_express_args, 2))
                    if not new_express_zuhe:
                        return new_vector_value
                    else:
                        new_vector_value = triangle_vector_simplify(new_express_zuhe, new_vector_value)
                        return new_vector_value


class XLTriangleSimplify(BaseFunction):
    def solver(self, *args):
        target = args[0].sympify()
        target_args = get_express_args(target)
        assert target_args
        target_zuhe = list(itertools.combinations(target_args, 2))
        aa = triangle_vector_simplify(target_zuhe, target)
        self.output.append(BaseExpression(aa))
        return self


if __name__ == '__main__':
    answer = XLTriangleSimplify().solver(BaseExpression("vector(BA)+vector(AF)+vector(CB)")).output[0].sympify()
